#pragma once
#include<iostream>
#include<string>
#include<memory>
#include<jsoncpp/json/json.h>
#include"Log.hpp"

static const std::string sep="\r\n";

std::string Encode(const std::string& jsonstr)
{
    std::string s=std::to_string(jsonstr.size());
    return s+sep+jsonstr+sep;
}

std::string Decode(std::string &packstream)
{
    auto pos=packstream.find(sep);
    if(pos==std::string::npos)
    {
        LOG(DEBUG,"decode error\n");
        std::cout<<"inbuffer:"<<packstream<<std::endl;
        return std::string();
    }
    std::string strlen=packstream.substr(0,pos);

    int len=std::stoi(strlen);
    int total=strlen.size()+len+2*sep.size();
    if(packstream.size()<total)return std::string();
    
    std::string jsonstr=packstream.substr(pos+sep.size(),len);
    packstream.erase(0,total);
    return jsonstr;
}

class Request
{
public:
    Request(int x,int y,char oper):_x(x),_y(y),_oper(oper)
    {}
    Request()
    {}
    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["x"]=_x;
        root["y"]=_y;
        root["oper"]=_oper;
        // Json::StyledWriter writer;

        Json::FastWriter writer;
        std::string s=writer.write(root);
        *out=s;
        return true;
    }
    bool DeSerialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool ret=reader.parse(in,root);
        if(!ret)return ret;
        _x=root["x"].asInt();
        _y=root["y"].asInt();
        _oper=root["oper"].asInt();
        return ret;

    }
    void Printf()
    {
        std::cout<<_x<<std::endl;
        std::cout<<_y<<std::endl;
        std::cout<<_oper<<std::endl;

    }
    int X()
    {
        return _x;
    }
    int Y()
    {
        return _y;
    }
    char Oper()
    {
        return _oper;
    }
    void SetValue(int x,int y,char oper)
    {
        _x=x;
        _y=y;
        _oper=oper;
    }
    ~Request()
    {}
private:
    int _x;
    int _y;
    char _oper;//+ - * /
};

class Response
{
public:
    Response():_result(0),_code(0),_desc("success")
    {}
    bool Serialize(std::string *out)
    {
         Json::Value root;
        root["result"]=_result;
        root["code"]=_code;
        root["desc"]=_desc;
        // Json::StyledWriter writer;
        Json::FastWriter writer;
        std::string s=writer.write(root);
        *out=s;
        return true;
    }
    bool DeSerialize(std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool ret=reader.parse(in,root);
        if(!ret)return ret;
        _result=root["result"].asInt();
        _code=root["code"].asInt();
        _desc=root["desc"].asString();
        return ret;
    }
    void PrintfResult()
    {
        std::cout<<"result:"<<_result<<" ,code:"<<_code<<" ,desc:"<<_desc<<std::endl;
    }
    ~Response()
    {}
public:
    int _result;
    int _code;//0:success 1:div zero 2:非法操作 状态码
    std::string _desc;
};


class Factory
{
public:
    static std::shared_ptr<Request> BuildRequestDefault()
    {
        return std::make_shared<Request>();
    }
    static std::shared_ptr<Response> BuildResponseDefault()
    {
        return std::make_shared<Response>();
    }
};